#include <signal.h>
#include <cstring>
#include <cerrno>
#include <iostream>
#include <pthread.h>
using namespace std;

#include "ThreadPool.h"
#include "WorkerThread.h"
using namespace yazi::thread;

#include "Singleton.h"
#include "Logger.h"
using namespace yazi::utility;

WorkerThread::WorkerThread(){

}

WorkerThread::~WorkerThread(){

}

void WorkerThread::cleanup(void* ptr){
    std::cout << "worker thread cleanup handler" << std::endl;
}

void WorkerThread::run(){
    sigset_t mask;
    int ret = sigfillset(&mask);
    if(ret == -1){
        perror("sigfillset()");
        return;
    }
    if(pthread_sigmask(SIG_SETMASK, &mask, NULL) < 0){
        perror("pthread_sugmask()");
        return;
    }
    pthread_cleanup_push(cleanup, (void*)this);

    while(true){
        m_mutex.lock();
        while(m_task == nullptr)
            m_cond.wait(&m_mutex);
        m_mutex.unlock();

        int oldstate = 0;
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);

        m_task->run();
        m_task->destroy();
        m_task = nullptr;
        
        Singleton<ThreadPool>::instance()->move_to_idle(this);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
        pthread_testcancel();
    }
    pthread_cleanup_pop(1);
}